package com.best.main;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * @author Jiang Akang
 * employeeId: BG435424
 * @date 2021/6/8
 **/
public class TransactionCallBackTest {
    private static String url = "jdbc:mysql://localhost:3306/spring_transaction?useSSL=false&characterEncoding=utf-8&autoReconnect=true";
    private static String user = "root";
    private static String password = "root";

    public static void main(String[] args) {
        // 获取数据源
        final DataSource ds = new DriverManagerDataSource(url, user, password);
        // 编程式事务
        final TransactionTemplate template = new TransactionTemplate();
        // 设置事务管理器
        template.setTransactionManager(new DataSourceTransactionManager(ds));
        Connection connection = DataSourceUtils.getConnection(ds);
        test1(template, connection);
        test2(template, connection);
    }

    // 方式一： 匿名内部类
    @SuppressWarnings("all")
    public static void test1(TransactionTemplate template,  Connection connection) {
        // TransactionCallback有返回值
        template.execute(new TransactionCallback<Object>() {
            @Override
            public Object doInTransaction(TransactionStatus status) {
                try {
                    // 插入
                    PreparedStatement prepare = connection.prepareStatement("insert into person(id, name) values (?, ?)");
                    prepare.setInt(1, 1);
                    prepare.setString(2, "jak");
                    prepare.executeUpdate();
                    // 模拟异常 NullPointerException
                    String str = null;
                    str.toLowerCase();
                    System.out.println("数据已插入");
                } catch (Exception e) {
                    System.out.println("更新失败");
                    status.setRollbackOnly();
                }
                return null;
            }
        });
    }

    // 方式二：lamda表达式
    @SuppressWarnings("all")
    public static void test2(TransactionTemplate template,  Connection connection) {
        template.execute((status) -> {
            try {
                // 插入
                PreparedStatement prepare = connection.prepareStatement("insert into person(id, name) values (?, ?)");
                prepare.setInt(1, 2);
                prepare.setString(2, "hyd");
                prepare.executeUpdate();
                // 模拟异常 NullPointerException
                String str = null;
                str.toLowerCase();
                System.out.println("数据已插入");
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (RuntimeException e) {
                System.out.println("更新失败");
                status.setRollbackOnly();
            }
            return null;
        });
    }

}
